1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 import java.awt.*;
36 import java.awt.event.*;
37 import java.awt.image.BufferedImage;
38 import java.awt.geom.Line2D;
39 import java.awt.geom.Rectangle2D;
40 import java.util.Date;
41 import javax.swing.*;
42 import javax.swing.border.EtchedBorder;
43 import javax.swing.border.TitledBorder;
44 import java.lang.management.*;
45
46
47
48
49
50
51 public class MemoryMonitor extends JPanel {
52
53 private static final long serialVersionUID = -3463003810776195761L;
54 static JCheckBox dateStampCB = new JCheckBox("Output Date Stamp");
55 public Surface surf;
56 JPanel controls;
57 boolean doControls;
58 JTextField tf;
59
60 static java.util.List<MemoryPoolMXBean> mpools =
61 ManagementFactory.getMemoryPoolMXBeans();
62
63 static int numPools = mpools.size();
64
65 public MemoryMonitor() {
66 setLayout(new BorderLayout());
67 setBorder(new TitledBorder(new EtchedBorder(), "Memory Monitor"));
68 add(surf = new Surface());
69 controls = new JPanel();
70 controls.setPreferredSize(new Dimension(135,80));
71 Font font = new Font("serif", Font.PLAIN, 10);
72 JLabel label = new JLabel("Sample Rate");
73 label.setFont(font);
74 label.setForeground(Color.red);
75 controls.add(label);
76 tf = new JTextField("1000");
77 tf.setPreferredSize(new Dimension(45,20));
78 controls.add(tf);
79 controls.add(label = new JLabel("ms"));
80 label.setFont(font);
81 label.setForeground(Color.red);
82 controls.add(dateStampCB);
83 dateStampCB.setFont(font);
84 addMouseListener(new MouseAdapter() {
85 @Override
86 public void mouseClicked(MouseEvent e) {
87 removeAll();
88 if ((doControls = !doControls)) {
89 surf.stop();
90 add(controls);
91 } else {
92 try {
93 surf.sleepAmount = Long.parseLong(tf.getText().trim());
94 } catch (Exception ex) {}
95 surf.start();
96 add(surf);
97 }
98 validate();
99 repaint();
100 }
101 });
102 }
103
104
105 public class Surface extends JPanel implements Runnable {
106
107 public Thread thread;
108 public long sleepAmount = 1000;
109 public int usageHistCount = 20000;
110 private int w, h;
111 private BufferedImage bimg;
112 private Graphics2D big;
113 private Font font = new Font("Times New Roman", Font.PLAIN, 11);
114 private int columnInc;
115 private float usedMem[][];
116 private int ptNum[];
117 private int ascent, descent;
118 private Rectangle graphOutlineRect = new Rectangle();
119 private Rectangle2D mfRect = new Rectangle2D.Float();
120 private Rectangle2D muRect = new Rectangle2D.Float();
121 private Line2D graphLine = new Line2D.Float();
122 private Color graphColor = new Color(46, 139, 87);
123 private Color mfColor = new Color(0, 100, 0);
124 private String usedStr;
125
126
127 public Surface() {
128 setBackground(Color.black);
129 addMouseListener(new MouseAdapter() {
130 @Override
131 public void mouseClicked(MouseEvent e) {
132 if (thread == null) start(); else stop();
133 }
134 });
135 usedMem = new float[numPools][];
136 ptNum = new int[numPools];
137 }
138
139 @Override
140 public Dimension getMinimumSize() {
141 return getPreferredSize();
142 }
143
144 @Override
145 public Dimension getMaximumSize() {
146 return getPreferredSize();
147 }
148
149 @Override
150 public Dimension getPreferredSize() {
151 return new Dimension(135,80);
152 }
153
154
155 @Override
156 public void paint(Graphics g) {
157
158 if (big == null) {
159 return;
160 }
161
162 big.setBackground(getBackground());
163 big.clearRect(0,0,w,h);
164
165
166 h = h / ((numPools + numPools%2) / 2);
167 w = w / 2;
168
169 int k=0;
170 for (int i=0; i < 2;i++) {
171 for (int j=0; j < (numPools + numPools%2)/ 2; j++) {
172 plotMemoryUsage(w*i,h*j,w,h,k);
173 if (++k >= numPools) {
174 i = 3;
175 j = (numPools + numPools%2)/ 2;
176 break;
177 }
178 }
179 }
180 g.drawImage(bimg, 0, 0, this);
181 }
182
183 public void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {
184
185 MemoryPoolMXBean mp = mpools.get(npool);
186 float usedMemory = mp.getUsage().getUsed();
187 float totalMemory = mp.getUsage().getMax();
188
189
190 big.setColor(Color.green);
191
192
193 big.drawString(String.valueOf((int)totalMemory/1024) + "K Max ", x1+4.0f, (float) y1 + ascent+0.5f);
194 big.setColor(Color.yellow);
195
196
197 big.drawString(mp.getName(), x1+x2/2, (float) y1 + ascent+0.5f);
198
199
200 usedStr = String.valueOf((int)usedMemory/1024)
201 + "K used";
202 big.setColor(Color.green);
203 big.drawString(usedStr, x1+4, y1+y2-descent);
204
205
206 float ssH = ascent + descent;
207 float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);
208 float blockHeight = remainingHeight/10;
209 float blockWidth = 20.0f;
210 float remainingWidth = (float) (x2 - blockWidth - 10);
211
212
213 big.setColor(mfColor);
214 int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);
215 int i = 0;
216 for ( ; i < MemUsage ; i++) {
217 mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,
218 blockWidth,(float) blockHeight-1);
219 big.fill(mfRect);
220 }
221
222
223 big.setColor(Color.green);
224 for ( ; i < 10; i++) {
225 muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,
226 blockWidth,(float) blockHeight-1);
227 big.fill(muRect);
228 }
229
230
231 if (remainingWidth <= 30) remainingWidth = (float)30;
232 if (remainingHeight <= ssH) remainingHeight = (float)ssH;
233 big.setColor(graphColor);
234 int graphX = x1+30;
235 int graphY = y1 + (int) ssH;
236 int graphW = (int) remainingWidth;
237 int graphH = (int) remainingHeight;
238
239 graphOutlineRect.setRect(graphX, graphY, graphW, graphH);
240 big.draw(graphOutlineRect);
241
242 int graphRow = graphH/10;
243
244
245 for (int j = graphY; j <= graphH+graphY; j += graphRow) {
246 graphLine.setLine(graphX,j,graphX+graphW,j);
247 big.draw(graphLine);
248 }
249
250
251 int graphColumn = graphW/15;
252
253 if (columnInc == 0) {
254 columnInc = graphColumn;
255 }
256
257 for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {
258 graphLine.setLine(j,graphY,j,graphY+graphH);
259 big.draw(graphLine);
260 }
261
262 --columnInc;
263
264
265 if (usedMem[npool] == null) {
266 usedMem[npool] = new float[usageHistCount];
267 ptNum[npool] = 0;
268 }
269
270
271 usedMem[npool][ptNum[npool]] = usedMemory;
272
273 big.setColor(Color.yellow);
274
275 int w1;
276 if (ptNum[npool] > graphW) {
277 w1 = graphW;
278 } else {
279 w1 = ptNum[npool];
280 }
281
282
283 for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool];
284 k++, j++) {
285 if (k != 0) {
286 if (usedMem[npool][k] != usedMem[npool][k-1]) {
287 int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));
288 int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));
289 big.drawLine(j-1, h1, j, h2);
290 } else {
291 int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));
292 big.fillRect(j, h1, 1, 1);
293 }
294 }
295 }
296 if (ptNum[npool]+2 == usedMem[npool].length) {
297
298 for (int j = 1;j < ptNum[npool]; j++) {
299 usedMem[npool][j-1] = usedMem[npool][j];
300 }
301 --ptNum[npool];
302 } else {
303 ptNum[npool]++;
304 }
305 }
306
307
308 public void start() {
309 thread = new Thread(this);
310 thread.setPriority(Thread.MIN_PRIORITY);
311 thread.setName("MemoryMonitor");
312 thread.start();
313 }
314
315
316 public synchronized void stop() {
317 thread = null;
318 notify();
319 }
320
321 @Override
322 public void run() {
323
324 Thread me = Thread.currentThread();
325
326 while (thread == me && !isShowing() || getSize().width == 0) {
327 try {
328 Thread.sleep(500);
329 } catch (InterruptedException e) { return; }
330 }
331
332 while (thread == me && isShowing()) {
333 Dimension d = getSize();
334 if (d.width != w || d.height != h) {
335 w = d.width;
336 h = d.height;
337 bimg = (BufferedImage) createImage(w, h);
338 big = bimg.createGraphics();
339 big.setFont(font);
340 FontMetrics fm = big.getFontMetrics(font);
341 ascent = (int) fm.getAscent();
342 descent = (int) fm.getDescent();
343 }
344 repaint();
345 try {
346 Thread.sleep(sleepAmount);
347 } catch (InterruptedException e) { break; }
348 if (MemoryMonitor.dateStampCB.isSelected()) {
349 System.out.println(new Date().toString() + " " + usedStr);
350 }
351 }
352 thread = null;
353 }
354 }
355
356
357
358 static class Memeater extends ClassLoader implements Runnable {
359 Object y[];
360 public Memeater() {}
361 @Override
362 public void run() {
363 y = new Object[10000000];
364 int k =0;
365 while(true) {
366 if (k == 5000000) k=0;
367 y[k++] = new Object();
368 try {
369 Thread.sleep(20);
370 } catch (Exception x){}
371
372
373 try {
374
375 for (int i=0; i<10; i++) {
376 loadNext();
377 }
378 } catch (ClassNotFoundException x) {
379
380 }
381
382 }
383
384 }
385
386 Class<?> loadNext() throws ClassNotFoundException {
387
388
389
390
391
392
393
394
395
396 int begin[] = {
397 0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,
398 0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,
399 0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,
400 0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,
401 0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,
402 0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,
403 0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };
404
405 int end [] = {
406 0x01, 0x00, 0x10,
407 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,
408 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
409 0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,
411 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,
412 0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
413 0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00 };
415
416
417
418
419 String name = "Test" + Integer.toString(count++);
420
421 byte value[];
422 try {
423 value = name.substring(4).getBytes("UTF-8");
424 } catch (java.io.UnsupportedEncodingException x) {
425 throw new Error();
426 }
427
428
429
430 int len = begin.length + value.length + end.length;
431 byte b[] = new byte[len];
432 int pos=0;
433 for (int i: begin) {
434 b[pos++] = (byte) i;
435 }
436 for (byte v: value) {
437 b[pos++] = v;
438 }
439 for (int e: end) {
440 b[pos++] = (byte) e;
441 }
442
443 return defineClass(name, b, 0, b.length);
444
445 }
446 static int count = 100000;
447
448 }
449
450 public static void main(String s[]) {
451 final MemoryMonitor demo = new MemoryMonitor();
452 WindowListener l = new WindowAdapter() {
453 @Override
454 public void windowClosing(WindowEvent e) {System.exit(0);}
455 @Override
456 public void windowDeiconified(WindowEvent e) { demo.surf.start(); }
457 @Override
458 public void windowIconified(WindowEvent e) { demo.surf.stop(); }
459 };
460 JFrame f = new JFrame("MemoryMonitor");
461 f.addWindowListener(l);
462 f.getContentPane().add("Center", demo);
463 f.pack();
464 f.setSize(new Dimension(400,500));
465 f.setVisible(true);
466 demo.surf.start();
467 Thread thr = new Thread(new Memeater());
468 thr.start();
469 }
470
471 }